package com.nsoft.html5npub.utils;

import android.app.Activity;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.util.Log;

public class SimpleGestureFilter extends SimpleOnGestureListener {
	
	public static interface SimpleGestureListener{
	     void onSwipe(int direction);
	     void onDoubleTap();
	}

	public final static int SWIPE_UP = 1;
	public final static int SWIPE_DOWN = 2;
	public final static int SWIPE_LEFT = 3;
	public final static int SWIPE_RIGHT = 4;
	
	public final static int MODE_TRANSPARENT = 0;
	public final static int MODE_SOLID = 1;
	public final static int MODE_DYNAMIC = 2;
	
	private final static int ACTION_FAKE = -13;	
	private int swipeMinDistance = 100;
	private int swipeMaxDistance = 350;
	private int swipeMinVelocity = 100;
	
	private int mode = MODE_DYNAMIC;
	private boolean running = true;
	private boolean tapIndicator = false;

	private Activity context;
	private GestureDetector detector;
	private SimpleGestureListener listener;

	public SimpleGestureFilter(Activity context,SimpleGestureListener sgl){
		this.context = context;
		this.detector = new GestureDetector(context, this);
		this.listener = sgl; 
	}
	
	public void onTouchEvent(MotionEvent event){
		if(!this.running)
			return;
		
		boolean result = this.detector.onTouchEvent(event);
		if(this.mode == MODE_SOLID){
		    event.setAction(MotionEvent.ACTION_CANCEL);
		}else if (this.mode == MODE_DYNAMIC) {
			if(event.getAction() == ACTION_FAKE) 
				event.setAction(MotionEvent.ACTION_UP);
			else if (result)
				event.setAction(MotionEvent.ACTION_CANCEL); 
			else if(this.tapIndicator){
				event.setAction(MotionEvent.ACTION_DOWN);
				this.tapIndicator = false;
			}
		}
	}
	
	public void setMode(int m){
		this.mode = m;
	}
		 
	public int getMode(){
		return this.mode;
	}

	public void setEnabled(boolean status){
		this.running = status;
	}
		 
	public void setSwipeMaxDistance(int distance){
		this.swipeMaxDistance = distance;
	}
		 
	public void setSwipeMinDistance(int distance){
		this.swipeMinDistance = distance;
	}
 
	public void setSwipeMinVelocity(int distance){
		this.swipeMinVelocity = distance;
	}
 
	public int getSwipeMaxDistance(){
		return this.swipeMaxDistance;
	}
 
	public int getSwipeMinDistance(){
		return this.swipeMinDistance;
	}
 
	public int getSwipeMinVelocity(){
		return this.swipeMinVelocity;
	}

	 @Override
	 public boolean onFling(MotionEvent e1, MotionEvent e2, 
			 float velocityX, float velocityY) {
	 
		 final float xDistance = Math.abs(e1.getX() - e2.getX());
		 final float yDistance = Math.abs(e1.getY() - e2.getY());

		 if(xDistance > this.swipeMaxDistance || 
				 yDistance > this.swipeMaxDistance)
			 return false;
		 
		 velocityX = Math.abs(velocityX);
		 velocityY = Math.abs(velocityY);
		 boolean result = false;
		 
		 if(velocityX > this.swipeMinVelocity && 
				 xDistance > this.swipeMinDistance){
			 if(e1.getX() > e2.getX()) /* right to left */
				 this.listener.onSwipe(SWIPE_LEFT);
			 else
				 this.listener.onSwipe(SWIPE_RIGHT);
			 
			 result = true;
		 }else if(velocityY > this.swipeMinVelocity && 
				 yDistance > this.swipeMinDistance){
			 if(e1.getY() > e2.getY()) /* bottom to up */
				 this.listener.onSwipe(SWIPE_UP);
			 else
				 this.listener.onSwipe(SWIPE_DOWN);
			 
			 result = true;
		 }

		 
		 return result;
	 }
	 
	 @Override
	 public boolean onSingleTapUp(MotionEvent e) {
		 this.tapIndicator = true;
		 return false;
	 }

	 @Override
	 public boolean onDoubleTap(MotionEvent arg0) {
		 this.listener.onDoubleTap();;
		 return true;
	 }

	 @Override
	 public boolean onDoubleTapEvent(MotionEvent arg0) {
		 return true;
	 }
	 
	 @Override
	 public boolean onSingleTapConfirmed(MotionEvent arg0) {
		 if(this.mode == MODE_DYNAMIC){ 
			 arg0.setAction(ACTION_FAKE); 
			 try{
				 this.context.dispatchTouchEvent(arg0);  
			 }catch(Exception e){
				 Log.e("SimpleGestureFilter.onSingleTapConfirmed()",
						 e.getClass()+": "+e.getMessage());
			 }
		 }
		 return false;
	 }
}
